其他适配

状态栏导航栏高度适配

状态栏

状态栏是否显示

/**
 * Return whether the status bar is visible.
 * @param activity The activity.
 * @return {@code true}: yes<br>{@code false}: no
 */
public static boolean isStatusBarVisible(@NonNull final Activity activity) {
    int flags = activity.getWindow().getAttributes().flags;
    return (flags & WindowManager.LayoutParams.FLAG_FULLSCREEN) == 0;
}

状态栏高度

/**
 * Return the status bar's height.
 *
 * @return the status bar's height
 */
public static int getStatusBarHeight() {
    if (mStatusBarHeight <= 0) {
        Resources resources = Resources.getSystem();
        int resourceId = resources.getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            mStatusBarHeight = resources.getDimensionPixelSize(resourceId);
        }
    }
    return mStatusBarHeight;
}

导航栏

导航栏是否显示

/**
 * Return whether the navigation bar visible.
 *
 * @param window The window.
 * @return {@code true}: yes<br>{@code false}: no
 */
public static boolean isNavBarVisible(@NonNull final Window window) {
    boolean isNoLimits = (window.getAttributes().flags
            & WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS) != 0;
    if (isNoLimits) return false;
    View decorView = window.getDecorView();
    int visibility = decorView.getSystemUiVisibility();
    return (visibility & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0;
}

导航栏高度

/**
* Return the navigation bar's height.
*
* @return the navigation bar's height
*/
public static int getNavBarHeight() {
    Resources res = Resources.getSystem();
    int resourceId = res.getIdentifier("navigation_bar_height", "dimen", "android");
    if (resourceId != 0) {
        return res.getDimensionPixelSize(resourceId);
    } else {
        return 0;
    }
}

华为底部手机导航栏适配

华为 EMUI 底部导航栏,有可以手动设置显示和隐藏底部导航栏的按钮

糗百方案

public static int getNavigationBarHeight(Activity activity) {
    if (activity == null) {
    return 0;
}
if (!isNavigationBarShow(activity)) {
    return 0;
}
Resources resources = activity.getResources();
int resourceId = resources.getIdentifier("navigation_bar_height",
                                         "dimen", "android");
int height = 0;
if (resourceId > 0) {
    //获取NavigationBar的高度
    height = resources.getDimensionPixelSize(resourceId);
}
return height;
}

public static boolean isNavigationBarShow(Activity context) {
    if (context == null) {
    return false;
}

if (isFullScreen(context)) {
    if (OSUtils.isMIUI()) {//小米系统判断虚拟键是否显示方法
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            if (Settings.Global.getInt(context.getContentResolver(), "force_fsg_nav_bar", 0) != 0) {
                //开启手势,不显示虚拟键
                return false;
            }
        }
    }
}

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
    Display display = context.getWindowManager().getDefaultDisplay();
    Point size = new Point();
    Point realSize = new Point();
    display.getSize(size);
    display.getRealSize(realSize);
    return realSize.y != size.y;
} else {
    boolean menu = ViewConfiguration.get(context).hasPermanentMenuKey();
    boolean back = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK);
    if (menu || back) {
        return false;
    } else {
        return true;
    }
}
}

上面默认的方式,可能有些机型不行

public final class NavgationBarUtils {
    /**
	* @return false 关闭了NavgationBar ,true 开启了
	*/
    public static boolean isNavBarVisible(Context context) {
        ViewGroup rootLinearLayout = findRootLinearLayout(context);
        int navigationBarHeight = 0;

        if (rootLinearLayout != null) {
            ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) rootLinearLayout.getLayoutParams();
            navigationBarHeight = layoutParams.bottomMargin;
        }
        if (navigationBarHeight == 0) {
            return false;
        } else {
            return true;
        }
    }
    /**
	* 导航栏高度,关闭的时候返回0,开启时返回对应值
	*/
    public static int getNavBarHeight(Context context) {
        ViewGroup rootLinearLayout = findRootLinearLayout(context);
        int navigationBarHeight = 0;
        if (rootLinearLayout != null) {
            ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) rootLinearLayout.getLayoutParams();
            navigationBarHeight = layoutParams.bottomMargin;
        }
        return navigationBarHeight;
    }
    /**
	* 从R.id.content从上遍历,拿到 DecorView 下的唯一子布局LinearLayout 获取对应的bottomMargin
	* 即可得到对应导航栏的高度,0为关闭了或没有导航栏
	*/
    private static ViewGroup findRootLinearLayout(Context context) {
        ViewGroup onlyLinearLayout = null;
        try {
            Window window = getWindow(context);
            if (window != null) {
                ViewGroup decorView = (ViewGroup) getWindow(context).getDecorView();
                Activity activity = getActivity(context);
                View contentView = activity.findViewById(android.R.id.content);
                if (contentView != null) {
                    View tempView = contentView;
                    while (tempView.getParent() != decorView) {
                        ViewGroup parent = (ViewGroup) tempView.getParent();
                        if (parent instanceof LinearLayout) {
                            //如果style设置了不带toolbar,mContentView上层布局会由原来的 ActionBarOverlayLayout->FitWindowsLinearLayout)
                            if (parent instanceof FitWindowsLinearLayout) {
                                tempView = parent;
                                continue;
                            } else {
                                onlyLinearLayout = parent;
                                break;
                            }
                        } else {
                            tempView = parent;
                        }
                    }
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return onlyLinearLayout;
    }
    private static Window getWindow(Context context) {
        if (getAppCompActivity(context) != null) {
            return getAppCompActivity(context).getWindow();
        } else {
            return scanForActivity(context).getWindow();
        }
    }
    private static Activity getActivity(Context context) {
		if (getAppCompActivity(context) != null) {
			return getAppCompActivity(context);
		} else {
			return scanForActivity(context);
		}
		}
		private static AppCompatActivity getAppCompActivity(Context context) {
			if (context == null) return null;
			if (context instanceof AppCompatActivity) {
				return (AppCompatActivity) context;
			} else if (context instanceof ContextThemeWrapper) {
				return getAppCompActivity(((ContextThemeWrapper) context).getBaseContext());
			}
			return null;
		}
		private static Activity scanForActivity(Context context) {
			if (context == null) return null;
	
			if (context instanceof Activity) {
				return (Activity) context;
			} else if (context instanceof ContextWrapper) {
				return scanForActivity(((ContextWrapper) context).getBaseContext());
			}
		return null;
	}

}

完整

生产环境可用

// BarUtils
public final class BarUtils {


    // ====== statusbar ======

    private static int mStatusBarHeight;

    /**
	* Return whether the status bar is visible.
	*
	* @param activity The activity.
	* @return {@code true}: yes<br>{@code false}: no
	*/
    public static boolean isStatusBarVisible(@NonNull final Activity activity) {
        int flags = activity.getWindow().getAttributes().flags;
        return (flags & WindowManager.LayoutParams.FLAG_FULLSCREEN) == 0;
    }

    /**
	* Return the status bar's height.
	*
	* @return the status bar's height
	*/
    public static int getStatusBarHeight() {
        if (mStatusBarHeight <= 0) {
            Resources resources = Resources.getSystem();
            int resourceId = resources.getIdentifier("status_bar_height", "dimen", "android");
            if (resourceId > 0) {
                mStatusBarHeight = resources.getDimensionPixelSize(resourceId);
            }
        }
        return mStatusBarHeight;
    }

    // ====== navigationbar ======

    /**
* Return whether the navigation bar visible.
*
* @param activity The activity.
* @return {@code true}: yes<br>{@code false}: no
*/
    public static boolean isNavBarVisible(@NonNull final Activity activity) {
        return isNavBarVisible(activity.getWindow());
    }

    /**
* Return whether the navigation bar visible. 没有考虑到沉浸式透明导航栏情况
*
* @param window The window.
* @return {@code true}: yes<br>{@code false}: no
*/
    public static boolean isNavBarVisible(@NonNull final Window window) {
        boolean isNoLimits = (window.getAttributes().flags
                              & WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS) != 0;
        if (isNoLimits) return false;
        View decorView = window.getDecorView();
        int visibility = decorView.getSystemUiVisibility();
        return (visibility & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0;
    }

    /**
* Return the navigation bar's height. 没有考虑到沉浸式透明导航栏情况
*
* @return the navigation bar's height
*/
    public static int getNavBarHeight() {
        Resources res = Resources.getSystem();
        int resourceId = res.getIdentifier("navigation_bar_height", "dimen", "android");
        if (resourceId != 0) {
            return res.getDimensionPixelSize(resourceId);
        } else {
            return 0;
        }
    }

    /**
* @return false 关闭了NavgationBar ,true 开启了。考虑了沉浸式导航栏情况
*/
    public static boolean isNavBarVisible(Context context) {
        ViewGroup rootLinearLayout = findRootLinearLayout(context);
        int navigationBarHeight = 0;

        if (rootLinearLayout != null) {
            ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) rootLinearLayout.getLayoutParams();
            navigationBarHeight = layoutParams.bottomMargin;
        }
        if (navigationBarHeight == 0) {
            return false;
        } else {
            return true;
        }
    }

        /**
        * 导航栏高度,关闭的时候返回0,开启时返回对应值。考虑了沉浸式导航栏情况
        */
        public static int getNavBarHeight(Context context) {
        ViewGroup rootLinearLayout = findRootLinearLayout(context);
        int navigationBarHeight = 0;
        if (rootLinearLayout != null) {
        ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) rootLinearLayout.getLayoutParams();
        navigationBarHeight = layoutParams.bottomMargin;
    }
        return navigationBarHeight;
    }

        /**
        * 从R.id.content从上遍历,拿到 DecorView 下的唯一子布局LinearLayout 获取对应的bottomMargin
        * 即可得到对应导航栏的高度,0为关闭了或没有导航栏
        */
        private static ViewGroup findRootLinearLayout(Context context) {
        ViewGroup onlyLinearLayout = null;
        try {
        Window window = getWindow(context);
        if (window != null) {
        ViewGroup decorView = (ViewGroup) getWindow(context).getDecorView();
        Activity activity = getActivity(context);
        View contentView = activity.findViewById(android.R.id.content);
        if (contentView != null) {
        View tempView = contentView;
        while (tempView.getParent() != decorView) {
        ViewGroup parent = (ViewGroup) tempView.getParent();
        if (parent instanceof LinearLayout) {
        //如果style设置了不带toolbar,mContentView上层布局会由原来的 ActionBarOverlayLayout->FitWindowsLinearLayout)
        if (parent instanceof FitWindowsLinearLayout) {
        tempView = parent;
        continue;
    } else {
        onlyLinearLayout = parent;
        break;
    }
    } else {
        tempView = parent;
    }
    }
    }
    }

    } catch (Exception e) {
        e.printStackTrace();
    }
        return onlyLinearLayout;
    }

        private static Window getWindow(Context context) {
        if (getAppCompActivity(context) != null) {
        return getAppCompActivity(context).getWindow();
    } else {
        return scanForActivity(context).getWindow();
    }
    }

        private static Activity getActivity(Context context) {
        if (getAppCompActivity(context) != null) {
        return getAppCompActivity(context);
    } else {
        return scanForActivity(context);
    }
    }

        private static AppCompatActivity getAppCompActivity(Context context) {
        if (context == null) return null;
        if (context instanceof AppCompatActivity) {
        return (AppCompatActivity) context;
    } else if (context instanceof ContextThemeWrapper) {
        return getAppCompActivity(((ContextThemeWrapper) context).getBaseContext());
    }
        return null;
    }

        private static Activity scanForActivity(Context context) {
        if (context == null) return null;

        if (context instanceof Activity) {
        return (Activity) context;
    } else if (context instanceof ContextWrapper) {
        return scanForActivity(((ContextWrapper) context).getBaseContext());
    }
        return null;
    }

    }

App 黑白化